package com.serkol.driving.learning.service.impl;

import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.crypto.digest.Digester;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.serkol.bean.LoginConfig;
import com.serkol.bean.MyPage;
import com.serkol.constant.AuthConstant;
import com.serkol.constant.ResultCode;
import com.serkol.driving.learning.entity.LoginLog;
import com.serkol.driving.learning.entity.Users;
import com.serkol.driving.learning.mapper.UsersMapper;
import com.serkol.driving.learning.service.UsersService;
import com.serkol.exception.AuthException;
import com.serkol.driving.learning.handler.MyLambdaQueryWrapper;
import com.serkol.modal.sql.SqlFeildModal;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author pingan
 * @description 针对表【users】的数据库操作Service实现
 * @createDate 2022-09-16 19:40:18
 */
@Service
public class UsersServiceImpl extends ServiceImpl<UsersMapper, Users>
        implements UsersService {

    @Override
    public Users findByLogin(String openid) {

        QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Users::getOpenid, openid);
        queryWrapper.last("LIMIT  1");
        return this.getOne(queryWrapper);
    }

    @Override
    public Users findByLoginAndInsert(Users usersDetail) {

        boolean b = this.saveOrUpdate(usersDetail);
        return usersDetail;
    }


    @Override
    public Users findByUserId(Long userId) {
        if (userId != null) {
            return this.getById(userId);
        } else {
            return null;
        }
    }

    @Override
    public Long findByUserCount(Long userId) {
        LambdaUpdateWrapper<Users> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();

        lambdaUpdateWrapper.eq(Users::getParentUserId, userId);
        return this.count(lambdaUpdateWrapper);
    }

    @Override
    public boolean editPhoneNumber(String phoneNumber) {
        LoginLog loginLog = AuthConstant.getLoginLog();
        LambdaUpdateWrapper<Users> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.set(Users::getPhone, phoneNumber);
        lambdaUpdateWrapper.eq(Users::getId, loginLog.getUserId());
        return this.update(lambdaUpdateWrapper);
    }

    @Override
    public Map<Integer, Users> getParentUsersLevel(Users byUserId) {
        Map<Integer, Users> map = new HashMap<>();
        map.put(1, byUserId);
        Users byUserId1 = findByUserId(byUserId.getParentUserId());
        if (byUserId1 != null) {
            map.put(2, byUserId1);
            Users byUserId2 = findByUserId(byUserId1.getParentUserId());
            if (byUserId2 != null) {
                map.put(3, byUserId2);
            }
        }
        return map;
    }

    @Override
    public List<Long> getParentUsersLevelIds(long parentId) {

   return  getParentUsersLevelIdL(parentId);
    }
    public List<Long> getParentUsersLevelIdL(long parentId) {
        List<Long> children = new ArrayList<>();

        MyLambdaQueryWrapper<Users> queryWrapper=new MyLambdaQueryWrapper<>();
        queryWrapper.eq(Users::getId,parentId);
        List<Users> list = this.list(queryWrapper);
        for (Users next : list) {
            children.add(next.getId());
            if (next.getParentUserId() != null && next.getParentUserId() > 0) {
                List<Long> findChildrensL = getParentUsersLevelIdL(next.getParentUserId());
                children.addAll(findChildrensL);
            }
        }
        return children;
    }

    @Override
    public List<Long> getFindChildrens(long parentId) {
        return getFindChildrensL(parentId);
    }
    public List<Long> getFindChildrensL(long parentId) {
        List<Long> children = new ArrayList<>();
        MyLambdaQueryWrapper<Users> queryWrapper=new MyLambdaQueryWrapper<>();
        queryWrapper.eq(Users::getParentUserId,parentId);
        List<Users> list = this.list(queryWrapper);
        for (Users next : list) {
            children.add(next.getId());
            if (next.getId() != null && next.getId() > 0) {
                List<Long> findChildrensL = getFindChildrensL(next.getId());
                children.addAll(findChildrensL);
            }
        }
        return children;
    }





    @Override
    public Users findByUserLogin(LoginConfig loginConfig) throws AuthException {
        Digester md5 = new Digester(DigestAlgorithm.MD5);
        String md5Hex1 = DigestUtil.md5Hex(loginConfig.getPassword());

        LambdaQueryWrapper<Users> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(Users::getUserName,loginConfig.getUserName()).eq(Users::getUserPassword,md5Hex1);
        Users login = this.getOne(queryWrapper);
      //  Users login = this.baseMapper.login(loginConfig.getUserName(), loginConfig.getPassword());
        if (login != null) {
            return login;
        } else {
            throw new AuthException(ResultCode.OK_CONTENT_NO, "mini.memberdoesnotexist");
        }
    }

    @Override
    public MyPage findByList(int pageSize, int current, String invite, String userName, String nickname, String phone) {

        QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
        queryWrapper.select(SqlFeildModal.getUsersFeild()).lambda().eq(Users::getDeleted, 0);

        if (StringUtils.isNotEmpty(invite)) {
            queryWrapper.lambda().likeRight(Users::getInvite, invite);
        }
        if (StringUtils.isNotEmpty(userName)) {
            queryWrapper.lambda().likeRight(Users::getUserName, userName);
        }
        if (StringUtils.isNotEmpty(nickname)) {
            queryWrapper.lambda().likeRight(Users::getNickname, nickname);
        }

        if (StringUtils.isNotEmpty(phone)) {
            queryWrapper.lambda().likeRight(Users::getPhone, phone);
        }

        queryWrapper.orderByDesc("ID");
        Page<Map<String, Object>> page = new Page<>(current, pageSize);
        Page<Map<String, Object>> mapPage = this.baseMapper.selectMapsPage(page, queryWrapper);
        return MyPage.parsePage(mapPage);
    }

    @Override
    public Map<String, Object> getCurrentUser() {
        LoginLog loginLog = AuthConstant.getLoginLog();
        QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
        queryWrapper.select(SqlFeildModal.getCurrentUser());
        queryWrapper.lambda().eq(Users::getId, loginLog.getUserId());
        return this.getMap(queryWrapper);
    }


    private List<Object> getFindIds(long parentUserId) {
        QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("IFNULL(ID,0)");
        if (parentUserId > 0) {
            queryWrapper.lambda().eq(Users::getParentUserId, parentUserId);
        }
//Long.parseLong(o.toString())
        List<Object> longs = this.listObjs((o) -> {
            System.out.println("NULLLLLL:" + o);

            return o;
        });
        longs.add(parentUserId);
        for (Object next : longs) {
            System.out.println("NULLLLLL1:" + next);
            if (next != null) {
                List<Object> findIds = this.getFindIds(Long.parseLong(next.toString()));
                longs.addAll(findIds);
            }
        }
        return longs;
    }



    @Override
    public Map<String, Object> findById(long id) {

        QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
        queryWrapper.select(SqlFeildModal.getUsersFullFeild());
        queryWrapper.lambda().eq(Users::getId, id);
        Map<String, Object> map = this.getMap(queryWrapper);
        return map;
    }

    @Override
    public boolean isPhoneValid(String phone) {
        QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Users::getPhone, phone);
        boolean exists = this.baseMapper.exists(queryWrapper);
        System.out.println("----------------------------------------------------");
        System.out.println(exists);
        return exists;
    }

    @Override
    public Users findByUserPhone(String phone) {
        QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Users::getPhone, phone);
        Users one = this.getOne(queryWrapper);
        return one;
    }

    @Override
    public boolean isPhoneAndIdValid(String phone, Long id) {
        QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Users::getPhone, phone).eq(Users::getId, id);
        boolean exists = this.baseMapper.exists(queryWrapper);
        return exists;
    }

    @Override
    public boolean isUsers(Long parentUserId) {
        QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Users::getId, parentUserId);
        boolean exists = this.baseMapper.exists(queryWrapper);
        return exists;
    }

    @Override
    public Map<String, Object> findByUserAuthPhone(String phone) {
        QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
        queryWrapper.select(SqlFeildModal.getUsersFullFeild());
        queryWrapper.lambda().eq(Users::getPhone, phone).last("LIMIT 1");
        Map<String, Object> map = this.getMap(queryWrapper);
        return map;
    }

    @Override
    public Map<String, Object> getUserStastic() {
        Map<String, Object> map = new HashMap<>();
        long count = this.count();
        map.put("users", count);
        LambdaQueryWrapper<Users> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Users::getDeleted, 0);
        long count1 = this.count(queryWrapper);
        map.put("agent", count1);

        return map;
    }

    @Override
    public boolean changeAvatar(Long userId, Long id, String url) {

        LambdaUpdateWrapper<Users> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.set(Users::getAvatar, url);
        lambdaUpdateWrapper.eq(Users::getId, userId);
        boolean update = this.update(lambdaUpdateWrapper);
        return update;
    }

    @Override
    public Map<String, Object> findBySuorceId(Long userId) {
        QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
        queryWrapper.select(SqlFeildModal.getUsersFullSourceFeild());
        queryWrapper.lambda().eq(Users::getId, userId);
        Map<String, Object> map = this.getMap(queryWrapper);
        return map;
    }


    private List<Map<String, Object>> getFindByIds(List<Map<String, Object>> list, long parentUserId) {
        if (list == null){
            list = new ArrayList<>();
        }
        MyLambdaQueryWrapper<Users> queryWrapper = new MyLambdaQueryWrapper<>();
        queryWrapper.select(Users::getId).authName(Users::getId).as("name").select(Users::getParentUserId).as("parentUserId");
        queryWrapper.eq(Users::getId, parentUserId);
        queryWrapper.last("LIMIT 1");
        MyLambdaQueryWrapper<Users> queryWrapper1 = new MyLambdaQueryWrapper<>();
        queryWrapper1.eq(Users::getId, parentUserId);
        if (this.baseMapper.exists(queryWrapper1)) {
            Map<String, Object> map = this.getMap(queryWrapper);
            list.add(map);
            if (map.containsKey("parentUserId")) {
                Object parentUserId1 = map.get("parentUserId");
                long l = Long.parseLong(String.valueOf(parentUserId1));
                if (l > 0) {

                    list = getFindByIds(list, l);
                    // list.addAll()
                }
            }

        }
        return list;
    }

    @Override
    public List<Map<String, Object>> findMyParentList(long userId) {
        List<Map<String, Object>>   list = new ArrayList<>();
        Users byId = getById(userId);
        return getFindByIds(list,byId.getParentUserId());
    }


}




